//
//  Simulation.h
//  phy_four
//
//  Created by Snir Gazit on 3/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef phy_four_Simulation_h
#define phy_four_Simulation_h
#include "../HelpLibs/def.h"
#include "Lattice.h"
#include "Move.h"
#include "Measure.h"
#include "../HelpLibs/RandomGen.h"
#include "../HelpLibs/QmcParameters.h"
#include "../HelpLibs/pugixml/pugixml.hpp"
#include "boost/chrono.hpp"
#include <gsl/gsl_sf_hyperg.h>
#include <gsl/gsl_sf_gamma.h>
#include <iostream>
#include "../HelpLibs/InputFile.h"

double calcW(double mu, double U, int m);
void calcWeight(double muIn, double UIn, double g, int maxBond,
		ostream &outFile, BoltzWeightType &weight);
double integrand(double r, void * inData);

// Worm Algorithm

class Worm {
	// Params
	QmcParameters qmcParameters_;
	// Configuration
	Lattice lat_;
	// Moves
	ShiftMove shiftMove_;
	JumpMove jumpMove_;
	// Measurements
	Measurements measures_;
	// Random Number Engine
	MTGen eng_;
	// Draw Next Move
	RandomVariable<MTGen, UniInt> openClose_;
	// OufPutFile
	ofstream outFile_;
public:
	~Worm();
	void init(QmcParameters &qmcParameters);
	bool run();
	void thermalize();
	bool checkNotDone();
	void nextMove();
	void dump();
	void read();
};

// WormLoop Algorithm

class WormLoop {
	// Params
	QmcParameters qmcParameters_;
	// Configuration
	Lattice lat_;
	// Moves
	CreateLoopMove CreateLoopMove_;
	// Measurements
	Measurements measures_;
	// Random Number Engine
	MTGen eng_;
	// OufPutFile
	ofstream outFile_;
	BoltzWeightType boltzRatio_;
public:
	~WormLoop();
	void init(QmcParameters &qmcParameters);
	bool run();
	void setCoupeling(double g);
	void thermalize();
	void simulatedAnnealing();
	bool checkNotDone();
	void nextMove();
	void dump();
	void read();
};

#endif
